﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Threading;

namespace MencoderModelNS
{
    class MencoderModel
    {
        public delegate void OutputHandler(string outStr);
        public event OutputHandler outputHandler;
        
        private string videoFilePath;
        private string outputPath;
        private string mencoderPath;

        private Process codingProcess;
        
        public enum CodingMethods : int
        {
            fastest,
            fast,
            tradeoff,
            good,
            best
        }
        
        
        public void killProcess() {
            if (codingProcess != null) {
                try
                {
                    codingProcess.Kill();
                }
                catch (Exception ex) { }
                
            }
            
        }

        

        private string argsStr;
        public string ArgsStr
        {
            get { return argsStr; }
            set { argsStr = value; }
        }

        public MencoderModel(string videoPath, string outputFilePath, string mencoderPth) {
            videoFilePath = videoPath;
            outputPath = outputFilePath;
            mencoderPath = mencoderPth;
        }

        public void creatArgs(string crf, int method)
        {
            if (method == (int) CodingMethods.best) {
                argsStr = String.Format("\"{0}\" -of rawvideo -nosound  -vf harddup -ffourcc H264 -ovc x264 -x264encopts crf={1}:threads=auto:qp_min=22:deblock=-2,-2:subq=8:me=umh:bframes=4:frameref=10:partitions=all:8x8dct:trellis=1:direct_pred=auto:weight_b:b_pyramid=normal:mixed_refs:b_adapt=2:psnr -o \"{2}\"", videoFilePath, crf, outputPath);
            }
            else if (method == (int)CodingMethods.fastest) {
                argsStr = String.Format("\"{0}\" -of rawvideo -nosound  -vf harddup -ffourcc H264 -ovc x264 -x264encopts crf={1}:threads=auto:qp_min=22:deblock=-2,-2:me=dia:subq=1:partitions=none:direct_pred=spatial:pb_factor=1.5:bframes=1:psnr -o \"{2}\"", videoFilePath, crf, outputPath);
            }
            else if (method == (int)CodingMethods.fast) {
                argsStr = String.Format("\"{0}\" -of rawvideo -nosound  -vf harddup -ffourcc H264 -ovc x264 -x264encopts crf={1}:threads=auto:qp_min=22:deblock=-2,-2:subq=1:psnr -o \"{2}\"", videoFilePath, crf, outputPath);
            }
            else if (method == (int)CodingMethods.tradeoff) {
                argsStr = String.Format("\"{0}\" -of rawvideo -nosound  -vf harddup -ffourcc H264 -ovc x264 -x264encopts crf={1}:threads=auto:qp_min=22:deblock=-2,-2:subq=3:psnr -o \"{2}\"", videoFilePath, crf, outputPath);
            }
            else if (method == (int)CodingMethods.good) {
                argsStr = String.Format("\"{0}\" -of rawvideo -nosound  -vf harddup -ffourcc H264 -ovc x264 -x264encopts crf={1}:threads=auto:qp_min=22:deblock=-2,-2:bframes=3:b_bias=5:b_pyramid=normal:weight_b:trellis=1:8x8dct:psnr -o \"{2}\"", videoFilePath, crf, outputPath);
            }
            
        }

        public void startCoding() {
            ProcessStartInfo start = new ProcessStartInfo();
            start.FileName = mencoderPath;
            start.Arguments = argsStr;
            start.UseShellExecute = false;
            start.RedirectStandardOutput = true;
            start.CreateNoWindow = true;

            using (Process process = Process.Start(start))
            {
                codingProcess = process;
                using (StreamReader reader = process.StandardOutput)
                {
                    string result;
                    while ((result = reader.ReadLine()) != null)
                    {
                        outputHandler(result + "\n");
                        //Console.WriteLine(result);
                        
                    }
                }
                codingProcess = null;
            }

            
        }

    }
}
